package mmc.resource;

import static org.lwjgl.opengl.GL11.*;

import java.nio.ByteBuffer;

import mmc.cell.Block;

import org.lwjgl.opengl.GL11;

public final class BlockTextures extends Texture{
	
	private static final int SIZE = 1024;
	private static final int PIXEL_PER_BLOCK = 64;
	private static final int BLOCK_PER_DIM = SIZE/PIXEL_PER_BLOCK;
	private static final int PIXEL_INDENT = 4;
	
	public BlockTextures() {
		super(glGenTextures());
		
		ByteBuffer buffer = ByteBuffer.allocateDirect(SIZE*SIZE*4);
		for(int i=0;i<SIZE;i++){
			for(int j=0;j<SIZE;j++){
				byte blockId = (byte)((i/PIXEL_PER_BLOCK + j/PIXEL_PER_BLOCK*BLOCK_PER_DIM)+Byte.MIN_VALUE);
				int row = i%PIXEL_PER_BLOCK;
				int col = j%PIXEL_PER_BLOCK;
				
				addPixel(buffer, blockId, row, col);
			}
		}
		buffer.flip();
		
		glBindTexture(GL_TEXTURE_2D,id);
		glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
		glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
		glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, SIZE, SIZE, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buffer);
	}
	
	private void addPixel(ByteBuffer buffer, byte blockId, int row, int col){
		
		if(blockId==Block.GRASS){
			buffer.put((byte)(Math.random()*20+30));
			buffer.put((byte)(Math.random()*100+50));
			buffer.put((byte)0);
		}else if(blockId==Block.EARTH){
			buffer.put((byte)(80+Math.random()*30));
			buffer.put((byte)(48+Math.random()*32));
			buffer.put((byte)0);
		}else if(blockId==Block.STONE){
			buffer.put((byte)(Math.random()*10+90));
			buffer.put((byte)(Math.random()*10+90));
			buffer.put((byte)(Math.random()*10+50));
		}else {
			if((row-col)*(row-col)<=4 || (row+col-PIXEL_PER_BLOCK)*(row+col-PIXEL_PER_BLOCK)<=4)
				buffer.put((byte)255);
			else
				buffer.put((byte)0);
			buffer.put((byte)0);
			buffer.put((byte)0);
		}
		
		buffer.put((byte)255);
	}
	
	public void setGlTexCoord(byte blockId, int pointNr){
		int picRow = blockId/BLOCK_PER_DIM;
		int picCol = blockId%BLOCK_PER_DIM;
		
		float yOffset = (picCol*PIXEL_PER_BLOCK+PIXEL_INDENT)/(float)SIZE;
		float yEnd = ((picCol+1)*PIXEL_PER_BLOCK-1-PIXEL_INDENT)/(float)SIZE;
		
		float xOffset = (picRow*PIXEL_PER_BLOCK+PIXEL_INDENT)/(float)SIZE;
		float xEnd = ((picRow+1)*PIXEL_PER_BLOCK-1-PIXEL_INDENT)/(float)SIZE;
		
		
		switch(pointNr){
		case 0:
			glTexCoord2f(xOffset, yOffset);
			break;
		case 1:
			glTexCoord2f(xOffset,yEnd);
			break;
		case 2:
			glTexCoord2f(xEnd,yEnd);
			break;
		case 3:
			glTexCoord2f(xEnd,yOffset);
			break;
		}
	}
	
	public void addTextureCoordinate(byte blockId, int pointNr, int dimension, int orientation, ByteBuffer buffer){
		int picRow = (blockId-(int)Byte.MIN_VALUE)/BLOCK_PER_DIM;
		int picCol = (blockId-(int)Byte.MIN_VALUE)%BLOCK_PER_DIM;
		
		float yOffset = (picCol*PIXEL_PER_BLOCK+PIXEL_INDENT)/(float)SIZE;
		float yEnd = ((picCol+1)*PIXEL_PER_BLOCK-1-PIXEL_INDENT)/(float)SIZE;
		
		float xOffset = (picRow*PIXEL_PER_BLOCK+PIXEL_INDENT)/(float)SIZE;
		float xEnd = ((picRow+1)*PIXEL_PER_BLOCK-1-PIXEL_INDENT)/(float)SIZE;
		
		
		switch(pointNr){
		case 0:
			buffer.putFloat(xOffset);
			buffer.putFloat(yOffset);
			break;
		case 1:
			buffer.putFloat(xOffset);
			buffer.putFloat(yEnd);
			break;
		case 2:
			buffer.putFloat(xEnd);
			buffer.putFloat(yEnd);
			break;
		case 3:
			buffer.putFloat(xEnd);
			buffer.putFloat(yOffset);
			break;
		}
	}
}
